<template>
  <div class="bar-list">
    <!--- 前缀插槽 -->
    <slot name="prepend"></slot>

    <chart-wrapper
      :loading="loading"
      :show="Array.isArray(list) && list.length > 0"
    >
      <ul
        :class="[
          layout,
          'col-' + layoutColumns,
          layoutColumns === 1 ? 'vertical-equal-division' : ''
        ]"
        class="list"
        finished
      >
        <li
          :class="{
            double: double,
            'vertical-equal-division-row': layoutColumns === 1
          }"
          :key="key"
          :style="{ cursor: $listeners.click ? 'pointer' : '' }"
          @click="$emit('click', item)"
          class="list-item"
          v-for="(item, key) of list"
        >
          <template v-if="layout === 'one-line'">
            <span class="col order" v-if="fields.order && order"
              >NO.{{ key + 1 }}</span
            >
            <span
              :title="fields.title && item.title"
              class="col title"
              v-if="item.title"
              >{{ item.title }}</span
            >

            <div
              :style="{
                height: (barHeight === 2 ? barHeight / 2 : barHeight) + 'px'
              }"
              class="col bar"
            >
              <div
                :style="{
                  height: barHeight + 'px',
                  width: getPercent(item) + '%',
                  top: barHeight === 2 ? '-1px' : '0'
                }"
                class="bar-inner"
              >
                <div
                  :style="{
                    height: barHeight / 2 + 'px',
                    top: '-' + barHeight / 2 + 'px'
                  }"
                  class="bar-light"
                ></div>
              </div>
            </div>
            <el-tooltip
              :content="getCount(item.count)"
              class="item"
              effect="dark"
              placement="top"
              v-if="fields.count && isValidValue(item.count) && portraitbar"
            >
              <span class="col count">{{ getCount(item.count) }}</span>
            </el-tooltip>
            <span
              class="col percent"
              v-if="fields.percent && isValidValue(item.percent)"
              >{{ (item.percent * 100).toFixed(2) }}%</span
            >
          </template>
          <template v-else-if="layout === 'two-line'">
            <div class="info">
              <span class="col order" v-if="fields.order && order"
                >NO.{{ key + 1 }}</span
              >
              <span
                :title="item.title"
                class="col title"
                v-if="fields.title && item.title"
                >{{ item.title }}</span
              >
              <el-tooltip
                :content="getCount(item.count)"
                class="item"
                effect="dark"
                placement="top"
                v-if="fields.count && isValidValue(item.count)"
              >
                <span class="col count">{{ getCount(item.count) }}</span>
              </el-tooltip>
              <span
                class="col percent"
                v-if="fields.percent && isValidValue(item.percent)"
                >{{ (item.percent * 100).toFixed(2) }}%</span
              >
            </div>

            <div
              :style="{
                height: (barHeight === 2 ? barHeight / 2 : barHeight) + 'px'
              }"
              class="col bar"
            >
              <div
                :style="{
                  height: barHeight + 'px',
                  width: getPercent(item) + '%',
                  top: barHeight === 2 ? '-1px' : '0'
                }"
                class="bar-inner"
              >
                <div
                  :style="{
                    height: barHeight / 2 + 'px',
                    top: '-' + barHeight / 2 + 'px'
                  }"
                  class="bar-light"
                ></div>
              </div>
            </div>
          </template>
          <!-- count字段隐藏，在percent tooltip中显示 -->
          <template v-else-if="layout === 'two-line-tooltip'">
            <div class="info">
              <span class="col order" v-if="fields.order && order"
                >NO.{{ key + 1 }}</span
              >
              <span
                :title="item.title"
                class="col title"
                v-if="fields.title && item.title"
                >{{ item.title }}</span
              >
              <el-tooltip
                :content="getCount(item.count)"
                class="item"
                effect="dark"
                placement="top"
              >
                <span
                  class="col percent"
                  v-if="fields.percent && isValidValue(item.percent)"
                  >{{ (item.percent * 100).toFixed(2) }}%</span
                >
              </el-tooltip>
            </div>

            <div
              :style="{
                height: (barHeight === 2 ? barHeight / 2 : barHeight) + 'px'
              }"
              class="col bar"
            >
              <div
                :style="{
                  height: barHeight + 'px',
                  width: getPercent(item) + '%',
                  top: barHeight === 2 ? '-1px' : '0'
                }"
                class="bar-inner"
              >
                <div
                  :style="{
                    height: barHeight / 2 + 'px',
                    top: '-' + barHeight / 2 + 'px'
                  }"
                  class="bar-light"
                ></div>
              </div>
            </div>
          </template>
        </li>
      </ul>
    </chart-wrapper>
  </div>
</template>

<script>
import ChartWrapper from "@/components/reservation/chart-wrapper";

export default {
  name: "BarList",

  components: { ChartWrapper },

  filters: {
    countFilter(status) {
      return ((status / this.allCount()) * 100).tofixes(2);
    }
  },

  props: {
    title: {
      type: String,
      default: ""
    },
    titleTip: {
      type: String,
      default: ""
    },
    subTitle: {
      type: String,
      default: ""
    },
    list: {
      type: Array,
      default: _ => []
    },
    double: {
      type: Boolean,
      default: false
    },
    loading: {
      type: Boolean,
      default: false
    },
    order: {
      type: Boolean,
      default: false
    },
    layout: {
      type: String,
      default: "one-line" // 布局方式。支持: one-line, two-line
    },
    layoutColumns: {
      type: Number,
      default: 1 // 布局列数
    },
    barHeight: {
      type: Number,
      default: 2
    },
    fields: {
      type: Object,
      default: () => ({
        order: true,
        title: true,
        count: true,
        percent: true
      })
    },
    portraitbar: {
      type: Boolean,
      default: true
    },
    countUnit: {
      type: String,
      default: ""
    }
  },

  data() {
    return {};
  },

  computed: {
    allCount() {
      let all = 0;
      this.list.map(item => (all += item.count));
      return all;
    },

    maxCount() {
      return Math.max(...this.list.map(item => item.count));
    }
  },

  methods: {
    getPercent(item) {
      // 没有percent或不显示percent时，最长bar为100%
      // 有percent且显示percent时，按percent显示bar的长度
      return item.percent && this.fields.percent
        ? item.percent * 100
        : item.count && this.maxCount
        ? (item.count / this.maxCount) * 100
        : 0;
    },
    getCount(count) {
      const n = parseFloat(count);
      // 大于1000的进行格式化 1000 -> 1,000
      if (n > 1000) {
        return `${n.toLocaleString()} ${this.countUnit}`;
      }
      return `${count} ${this.countUnit}`;
    },

    isValidValue(val) {
      return val !== undefined && val !== null;
    }
  }
};
</script>

<style lang="scss" scoped>
@import "./vars.module.scss"; //引入方式

$header-height: 40px;
$light-width: 40px;
$content-height: calc(100% - #{$header-height});

.bar-list {
  height: 100%;
}

::v-deep .list {
  height: $content-height;

  .double {
    width: calc(calc(100% - 30px) / 2);
    display: inline-block;
  }
  .double:nth-child(even) {
    margin-left: 30px;
  }

  &.one-line {
    .list-item {
      display: flex;
      align-items: center;
    }
  }

  &.two-line {
    .info {
      display: flex;
    }

    .order,
    .title,
    .count,
    .percent {
      margin-right: 0;
    }

    .title {
      min-width: 60px;
      flex: 1;
    }

    .list-item {
      .bar {
        width: 100%;
        margin: 3px 0 0;
      }
    }
  }

  &.two-line-tooltip {
    .info {
      display: flex;
    }

    .order,
    .title,
    .count,
    .percent {
      margin-right: 0;
    }

    .title {
      min-width: 60px;
      flex: 1;
    }

    .list-item {
      .bar {
        width: 100%;
        margin: 3px 0 0;
      }
    }
  }

  &.col-2 {
    display: flex;
    flex-wrap: wrap;
  }

  /* 分列 */
  &.col-2,
  &.col-3 {
    font-size: 0;

    .list-item {
      /* 不要用浮动,导致弹窗高度撑不开!! */
      /* float: left; */
      margin-right: 40px;
    }
  }

  &.col-1 .list-item {
    width: 100%;
  }

  &.col-2 .list-item {
    width: calc(100% / 2 - 20px);

    &:nth-child(2n + 2) {
      margin-right: 0;
    }
  }

  &.col-3 .list-item {
    width: calc(100% / 3 - 80px / 3);

    &:nth-child(3n + 3) {
      margin-right: 0;
    }
  }
}

.list-item {
  position: relative;

  font-size: 0;
  margin-top: 12px;

  .col {
    height: 24px;
    line-height: 24px;
    display: inline-block;
    font-size: $font-size-small;
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
  }

  .order {
    width: 48px;
    margin-right: 5px;
  }
  .title {
    width: 60px;
    margin-right: 16px;
    text-align: left;
  }
  .bar {
    flex: 1 1 auto;
    margin-right: 16px;
    background: $background-color-light;
    position: relative;
    overflow: visible;

    .bar-inner {
      position: absolute;
      top: 0;
      left: 0;
      display: inline-block;
      background-color: $color-primary;
      overflow: hidden;
    }

    .bar-light {
      position: absolute;
      width: $light-width;
      border-radius: 2px;
      bottom: 0;
      box-shadow: 3px 1px 6px 0 #fff1de, -3px 1px 6px 0 #fff1de;
      animation-name: move;
      animation-duration: 1.5s;
      animation-timing-function: linear;
      animation-delay: 1s;
      animation-iteration-count: infinite;
    }
  }
  .count {
    width: 72px;
    text-align: right;
    color: #a7aeb6;
  }
  .percent {
    width: 43px;
    margin-left: 12px;
    text-align: right;
    color: #807c78;
  }
}

@keyframes move {
  from {
    transform: translateX(-100%);
  }

  to {
    transform: translateX(1000%);
  }
}
</style>
